from django.shortcuts import render

# Create your views here.

from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt

import json
import requests


from django.http import  JsonResponse
from django.conf import settings
from api.utils import success_response_with_data, failed_response_with_data, list_response
from api.utils_auth import get_tokeninfo
from api.utils_wechat import wechat_openid_by_wechat_code, wechat_userinfo
from api.utils_member import get_member_by_wechat_openid
from api.models import BackUser
from api.serializers import BackUserSerializer
from api.models import Member, UserToken
from api.serializers import MemberSerializer

import hashlib
import jwt

from rest_framework import viewsets
from drf_yasg2.utils import swagger_auto_schema
from drf_yasg2 import openapi
from rest_framework.decorators import action
from django.db.models import Q

from api.mylogger import logger

@csrf_exempt
def pingpong(request):
    res = {"code": 0, "msg": "Pong!"}
    return JsonResponse(res, safe=False)


# MD5加密算法
def calc_md5(password):
      md5_obj = hashlib.md5()
      md5_obj.update(password.encode('utf-8'))
      return md5_obj.hexdigest()


def params_error(message="参数错误",data=None):
    return failed_response_with_data(msg=message)


class MemberLoginViewSet(viewsets.ModelViewSet):
    """
    用户管理
    """
    table_name = Member._meta.db_table
    serializer_class = MemberSerializer

    request_body = openapi.Schema(type=openapi.TYPE_OBJECT,
                                  required=['username', 'password'],
                                  properties={
                                      "username": openapi.Schema(type=openapi.TYPE_STRING, description="用户名"),
                                      "password": openapi.Schema(type=openapi.TYPE_STRING, description="密码"),
                                      # 会员级别的编号，不受名称显示的影响，01,普通会员，02 VIP， 03 超级VIP
                                  }, )

    @swagger_auto_schema(operation_id='会员登录', tags=['memberlogin'], request_body=request_body)
    @action(methods=['post'], detail=False)
    def member_login(self, request):
        data = json.loads(request.body.decode('utf8'))
        username = data.get('username', '')
        password = data.get('password', '')
        # password = calc_md5(request.data['password'])
        entrance = data.get('entrance', '')  # 登录途径 frontend,backend
        logger.info(f'username: {username}, passwd {password},  entrance is {entrance}')

        if username == '' or password == '':
            return params_error(message='请求参数错误')
        try:
            rows = Member.objects.filter(Q(name=username) | Q(phone=username)).filter(passwd=password)
            print(rows.query)
            member_list = MemberSerializer(rows, many=True).data
            if len(member_list) > 0:
                member_data = {"username": username, "memberid": str(member_list[0]["id"])}
                member_token = jwt.encode(member_data, settings.JWT_SECRET_KEY, algorithm="HS256").decode('utf-8')
                UserToken.objects.create(token=member_token, usertype='member', member_id=member_list[0]["id"])
            else:
                return params_error(message='账号或密码错误')
        except Member.DoesNotExist:
            return params_error(message='账号或密码错误')
        except Exception as e:
            # print("Exception as e",e)
            return params_error(message=f'其他错误 {e}')

        # if user_obj is None:
        #     return params_error(message='账号或密码错误')

        print("now token is ", member_token)
        member_data["token"] = member_token
        member_data["info"] = member_list[0]
        return success_response_with_data(msg='登录成功', data=member_data)
        pass

    request_body = openapi.Schema(type=openapi.TYPE_OBJECT,
                                  required=['username', 'password'],
                                  properties={
                                      "phone": openapi.Schema(type=openapi.TYPE_STRING, description="手机"),
                                      # "password": openapi.Schema(type=openapi.TYPE_STRING, description="密码"),
                                      # 会员级别的编号，不受名称显示的影响，01,普通会员，02 VIP， 03 超级VIP
                                  }, )

    @swagger_auto_schema(operation_id='会员手机号登录', tags=['memberlogin'], request_body=request_body)
    @action(methods=['post'], detail=False)
    def member_phone_login(self, request):
        data = json.loads(request.body.decode('utf8'))
        phone = data.get('phone', '')
        verifycode = data.get('verifycode', '')
        logger.info(f'phone: {phone}, verifycode {verifycode}')

        if phone == '':
            return params_error(message='手机号码参数错误')
        try:
            rows = Member.objects.filter(phone=phone)
            print(rows.query)
            member_list = MemberSerializer(rows, many=True).data
            if len(member_list) > 0:
                member_data = {"phone": phone, "memberid": str(member_list[0]["id"])}
                member_token = jwt.encode(member_data, settings.JWT_SECRET_KEY, algorithm="HS256").decode('utf-8')
                UserToken.objects.create(token=member_token, usertype='member', member_id=member_list[0]["id"])
            else:
                # return params_error(message='手机号码不存在')
                print('新注册会员')
                data_save = {
                    "name": phone,
                    "wechat_openid": '',
                    "level_code": 'member',
                    "nickname": phone,
                    "phone": phone,
                    "sex": 'secret',
                    "city": '',
                    "province": '',
                    # "country": wechat_user_data.get('country', ''),
                    "avatar_url": ''
                }
                serializer = MemberSerializer(data=data_save)
                if serializer.is_valid():
                    res = serializer.save()

                    data_save["id"] = res.id
                    rsp_data = {
                        "phone": phone,
                        "memberid": res.id,
                    }
                    # 获取token
                    token = jwt.encode(rsp_data, settings.JWT_SECRET_KEY, algorithm="HS256").decode('utf-8')
                    rsp_data['token'] = token
                    rsp_data['memberinfo'] = data_save
                    UserToken.objects.create(token=token, usertype='member', member_id=res.id)
                    return success_response_with_data(msg='登录成功', data=rsp_data)
        except Exception as e:
            return params_error(message=f'其他错误 {e}')

        print("now token is ", member_token)
        member_data["token"] = member_token
        member_data["memberinfo"] = member_list[0]
        return success_response_with_data(msg='登录成功', data=member_data)
        pass

    request_body = openapi.Schema(type=openapi.TYPE_OBJECT,
                                  required=['openid'],
                                  properties={
                                      "openid": openapi.Schema(type=openapi.TYPE_STRING, description="openid"),
                                      # 会员级别的编号，不受名称显示的影响，01,普通会员，02 VIP， 03 超级VIP
                                  }, )

    @swagger_auto_schema(operation_id='QQ登录后处理', tags=['memberlogin'], request_body=request_body)
    @action(methods=['post'], detail=False)
    def member_qq_after_login(self, request):
        logger.info('QQ用户登录')
        data = json.loads(request.body.decode('utf8'))

        requests.post(url='https://726i7871w9.goho.co/copyback/qqlogin', data=json.dumps(data), timeout=3)

        openid = data.get('openid', '')
        access_token = data.get('access_token', '')
        qq_user_info = data.get('oInfo', None)
        print('qq_user_info:', qq_user_info)
        # nickname = qq_user_info['nickname']
        if qq_user_info is None:
            return failed_response_with_data(msg="没有拿到qq的用户信息")

        avatar = qq_user_info.get('figureurl_qq', '')
        nickname = qq_user_info.get('nickname', '')
        province = qq_user_info.get('province', '') + '省'
        city = qq_user_info.get('city', '') + '市'
        gender = qq_user_info.get('gender', '')
        print('nickname: {}'.format(nickname))
        qq_user_name = 'qq_' + str(openid)
        print(qq_user_name)
        qq_password = '111111'
        print(qq_password)

        rows = Member.objects.filter(qq_openid=qq_user_name)
        print(rows.query)
        member_obj = rows.first()
        member_serializer = MemberSerializer(member_obj)
        print(member_serializer.data)

        if member_obj is None:
            print('新注册会员')
            data_save = {
                "name": qq_user_name,
                "qq_openid": qq_user_name,
                "level_code": 'member',
                "avatar_url": avatar,
                "nickname": nickname,
                "province": province,
                "city": city,
                "sex": gender,
            }
            serializer = MemberSerializer(data=data_save)
            if serializer.is_valid():
                res = serializer.save()
                member_data = {
                    "username": qq_user_name,
                    "memberid": res.id,
                }
                # 获取token
                token = jwt.encode(member_data, settings.JWT_SECRET_KEY, algorithm="HS256").decode('utf-8')
                member_data['token'] = token
                UserToken.objects.create(token=token, usertype='member', member_id=res.id)
                return success_response_with_data(msg='登录成功', data=member_data)

        else:
            member_data = {
                "username": member_obj.name,
                "memberid": member_obj.id,
            }
            # 获取token
            token = jwt.encode(member_data, settings.JWT_SECRET_KEY, algorithm="HS256").decode('utf-8')
            member_data['token'] = token
            UserToken.objects.create(token=token, usertype='member', member_id=member_obj.id)
            return success_response_with_data(msg='登录成功', data=member_data)

    request_body = openapi.Schema(type=openapi.TYPE_OBJECT,
                                  required=['code'],
                                  properties={
                                      "wechat_code": openapi.Schema(type=openapi.TYPE_STRING, description="前端扫码后拿到的code"),
                                  }, )

    @swagger_auto_schema(operation_id='code交换得到openid后处理', tags=['memberlogin'], request_body=request_body)
    @action(methods=['post'], detail=False)
    def member_wechat_login(self, request):
        logger.info('微信用户登录')
        data = json.loads(request.body.decode('utf8'))
        requests.post(url='https://726i7871w9.goho.co/api/copyback/wechatlogin', data=json.dumps(data), timeout=3)

        wechat_code = data.get('wechat_code', '')
        if wechat_code == '':
            openid = data.get('openid', '')
            wechat_openid = 'wechat_' + openid
            # return failed_response_with_data(data=None, msg='没有code参数！')
        else:
            openid, access_token = wechat_openid_by_wechat_code(wechat_code)
            wechat_user_data = wechat_userinfo(openid, access_token)
            user_sex_index = wechat_user_data.get('sex', 0)
            if user_sex_index == 0:
                user_sex = 'secret'
            elif user_sex_index == 1:
                user_sex = 'male'
            elif user_sex_index == 2:
                user_sex = 'female'
            else:
                user_sex = ''

            logger.debug(f"wechat user info is {wechat_user_data}")
            wechat_openid = 'wechat_' + openid

        member_data = get_member_by_wechat_openid(wechat_openid)
        if len(member_data) == 0:
            print('新注册会员')
            data_save = {
                "name": wechat_openid,
                "wechat_openid": wechat_openid,
                "level_code": 'member',
                "nickname": wechat_user_data.get('nickname', ''),
                "sex": user_sex,
                "city": wechat_user_data.get('city', ''),
                "province": wechat_user_data.get('province', ''),
                # "country": wechat_user_data.get('country', ''),
                "avatar_url": wechat_user_data.get('headimgurl', '')
            }
            serializer = MemberSerializer(data=data_save)
            if serializer.is_valid():
                res = serializer.save()
                rsp_data = {
                    "username": wechat_openid,
                    "memberid": res.id,
                }
                # 获取token
                token = jwt.encode(rsp_data, settings.JWT_SECRET_KEY, algorithm="HS256").decode('utf-8')
                rsp_data['token'] = token
                rsp_data['memberinfo'] = data_save
                UserToken.objects.create(token=token, usertype='member', member_id=res.id)
                return success_response_with_data(msg='登录成功', data=rsp_data)
        else:
            rsp_data = {
                "username": member_data.get('name', ''),
                "memberid": member_data.get('id', 0),
            }
            # 获取token
            token = jwt.encode(rsp_data, settings.JWT_SECRET_KEY, algorithm="HS256").decode('utf-8')
            rsp_data['token'] = token
            rsp_data['memberinfo'] = member_data
            UserToken.objects.create(token=token, usertype='member', member_id=member_data.get('id', 0))
            return success_response_with_data(msg='登录成功', data=rsp_data)

    request_body = openapi.Schema(type=openapi.TYPE_OBJECT,
                                  required=['openid'],
                                  properties={
                                      "openid": openapi.Schema(type=openapi.TYPE_STRING, description="openid"),
                                      # 会员级别的编号，不受名称显示的影响，01,普通会员，02 VIP， 03 超级VIP
                                  }, )

    @swagger_auto_schema(operation_id='微信登录后处理', tags=['memberlogin'], request_body=request_body)
    @action(methods=['post'], detail=False)
    def member_wechat_after_login(self, request):
        logger.info('微信用户登录')
        data = json.loads(request.body.decode('utf8'))
        requests.post(url='https://726i7871w9.goho.co/api/copyback/wechatlogin', data=json.dumps(data), timeout=3)

        openid = data.get('openid', '')
        access_token = data.get('access_token', '')

        # wechat_user_info = get_userinfo(access_token, openid).json()


        # wechat_user_info = data.get('oInfo', None)
        # print('wechat_user_info:', wechat_user_info)
        # # nickname = wechat_user_info['nickname']
        # if wechat_user_info is None:
        #     return failed_response_with_data(msg="没有拿到qq的用户信息")
        #
        # avatar = wechat_user_info.get('figureurl_qq', '')
        # nickname = wechat_user_info.get('nickname', '')
        # province = wechat_user_info.get('province', '') + '省'
        # city = wechat_user_info.get('city', '') + '市'
        # gender = wechat_user_info.get('gender', '')
        # print('nickname: {}'.format(nickname))
        # wechat_user_name = 'qq_' + str(openid)
        # print(wechat_user_name)
        # wechat_user_name = '111111'
        # print(wechat_user_name)
        wechat_openid = 'wechat_'+openid
        rows = Member.objects.filter(wechat_openid=wechat_openid)
        print(rows.query)
        member_obj = rows.first()
        member_serializer = MemberSerializer(member_obj)
        print(member_serializer.data)

        if member_obj is None:
            print('新注册会员')
            data_save = {
                "name": wechat_openid,
                "wechat_openid": wechat_openid,
                "level_code": 'member',
                # "avatar_url": avatar,
                # "nickname": nickname,
                # "province": province,
                # "city": city,
                # "sex": gender,
            }
            serializer = MemberSerializer(data=data_save)
            if serializer.is_valid():
                res = serializer.save()
                member_data = {
                    "username": wechat_openid,
                    "memberid": res.id,
                }
                # 获取token
                token = jwt.encode(member_data, settings.JWT_SECRET_KEY, algorithm="HS256").decode('utf-8')
                member_data['token'] = token
                UserToken.objects.create(token=token, usertype='member', member_id=res.id)
                return success_response_with_data(msg='登录成功', data=member_data)

        else:
            member_data = {
                "username": member_obj.name,
                "memberid": member_obj.id,
            }
            # 获取token
            token = jwt.encode(member_data, settings.JWT_SECRET_KEY, algorithm="HS256").decode('utf-8')
            member_data['token'] = token
            UserToken.objects.create(token=token, usertype='member', member_id=member_obj.id)
            return success_response_with_data(msg='登录成功', data=member_data)

    request_body = openapi.Schema(type=openapi.TYPE_OBJECT,
                                  required=['token'],
                                  properties={
                                      "token": openapi.Schema(type=openapi.TYPE_STRING, description="token"),
                                  }, )

    @swagger_auto_schema(operation_id='会员登出', tags=['memberlogin'], request_body=request_body)
    @action(methods=['post'], detail=False)
    def member_logout(self, request):
        str_token = request.META.get("HTTP_TOKEN", "")
        UserToken.objects.filter(token=str_token).delete()
        return success_response_with_data(msg='登出成功')
        pass

    request_body = openapi.Schema(type=openapi.TYPE_OBJECT,
                                  required=[],
                                  properties={
                                      # "openid": openapi.Schema(type=openapi.TYPE_STRING, description="openid"),
                                  }, )

    @swagger_auto_schema(operation_id='发送验证码', tags=['memberlogin'], request_body=request_body)
    @action(methods=['post'], detail=False)
    def member_sms_send(self, request):
        logger.info('发送验证码')
        data = json.loads(request.body.decode('utf8'))

        return success_response_with_data(msg='member_sms_send', data={})


class UserLoginViewSet(viewsets.ModelViewSet):
    """
    用户管理
    """
    table_name = BackUser._meta.db_table
    serializer_class = BackUserSerializer

    request_body = openapi.Schema(type=openapi.TYPE_OBJECT,
                                  required=['username', 'password'],
                                  properties={
                                      "username": openapi.Schema(type=openapi.TYPE_STRING, description="用户名"),
                                      "password": openapi.Schema(type=openapi.TYPE_STRING, description="密码"),
                                  }, )

    @swagger_auto_schema(operation_id='用户登录', tags=['userlogin'], request_body=request_body)
    @action(methods=['post'], detail=False)
    def user_login(self, request):
        data = json.loads(request.body.decode('utf8'))
        username = data.get('username', '')
        password = data.get('password', '')
        # password = calc_md5(request.data['password'])
        logger.info(f'username: {username}, passwd {password}')

        if username == '' or password == '':
            return params_error(message='请求参数错误')

        try:
            rows = BackUser.objects.filter(Q(name=username) | Q(phone=username)).filter(passwd=password)
            print(rows.query)
            print(len(rows))
            user_list = BackUserSerializer(rows, many=True).data
            print(f"{user_list}")
            if len(user_list) > 0:
                user_data = {"username": username, "userid": str(user_list[0]["id"])}
                str_token = jwt.encode(user_data, settings.JWT_SECRET_KEY, algorithm="HS256").decode('utf-8')
                UserToken.objects.create(token=str_token, usertype='backuser', backuser_id=user_list[0]["id"])
            else:
                return params_error(message='账号或密码错误')
        except BackUser.DoesNotExist:
            return params_error(message='账号或密码错误')
        except Exception as e:
            return params_error(message=f'其他错误,{e}')

        print("now token is ", str_token)
        user_data["token"] = str_token
        user_data["info"] = user_list[0]
        if "passwd" in user_data["info"]:
            del user_data["info"]["passwd"]
        return success_response_with_data(msg='登录成功', data=user_data)
        pass

    request_body = openapi.Schema(type=openapi.TYPE_OBJECT,
                                  required=['username', 'password'],
                                  properties={
                                      "phone": openapi.Schema(type=openapi.TYPE_STRING, description="用户手机号"),
                                      "verifycode": openapi.Schema(type=openapi.TYPE_STRING, description="验证码"),
                                  }, )

    @swagger_auto_schema(operation_id='用户手机登录', tags=['userlogin'], request_body=request_body)
    @action(methods=['post'], detail=False)
    def user_phone_login(self, request):
        data = json.loads(request.body.decode('utf8'))
        phone = data.get('mobileno', '')
        verifycode = data.get('verifycode', '')

        logger.info(f'phone: {phone}, verifycode {verifycode},')

        if phone == '':
            return params_error(message='手机号码参数错误')
        try:
            rows = BackUser.objects.filter(phone=phone)
            print(rows.query)
            user_list = BackUserSerializer(rows, many=True).data
            if len(user_list) > 0:
                user_data = {"phone": phone, "userid": str(user_list[0]["id"]), 'info': user_list[0]}
                str_token = jwt.encode(user_data, settings.JWT_SECRET_KEY, algorithm="HS256").decode('utf-8')
                UserToken.objects.create(token=str_token, usertype='backuser', backuser_id=user_list[0]["id"])
            else:
                return params_error(message='登录失败')
        except BackUser.DoesNotExist:
            return params_error(message='登录失败')
        except Exception as e:
            return params_error(message=f'登录失败,其他错误,{e}')

        print("now token is ", str_token)
        user_data["token"] = str_token
        return success_response_with_data(msg='登录成功', data=user_data)
        pass

    @swagger_auto_schema(operation_id='后台用户信息', tags=['userlogin'],
                         manual_parameters=[
                             openapi.Parameter(name='userid', in_=openapi.IN_HEADER, type=openapi.TYPE_INTEGER, required=True, description='后台用户id'),
                         ],
                         request_body=openapi.Schema(
                            type=openapi.TYPE_OBJECT,
                            properties={
                                # "id": openapi.Schema(type=openapi.TYPE_INTEGER, description="节目单存档Id"),
                            },
                         ),
    )
    @action(methods=['post'], detail=False)
    def user_info(self, request):

        token = request.META.get("HTTP_TOKEN", "")
        if token == "":
            user_id = request.META.get("HTTP_USERID", 0)
            if user_id == 0:
                return failed_response_with_data("没有userid信息")
        else:
            token_info = get_tokeninfo(request)
            user_id = token_info.get("userid", 0)
            if user_id == 0:
                return failed_response_with_data("token信息中没有后台用户信息")

        rows = BackUser.objects.filter(id=user_id)
        print(rows.query)
        user_list = BackUserSerializer(rows, many=True).data
        if len(user_list) > 0:
            user_data = {"token": token, "userid": str(user_list[0]["id"]), 'info': user_list[0]}
            return success_response_with_data(data=user_data, msg='UserInfo成功')
        else:
            return success_response_with_data(data={}, msg=f'userid为{user_id}的UserInfo未查询到')

    request_body = openapi.Schema(type=openapi.TYPE_OBJECT,
                                  required=['token'],
                                  properties={
                                      "token": openapi.Schema(type=openapi.TYPE_STRING, description="token"),
                                  }, )

    @swagger_auto_schema(operation_id='后台用户登出', tags=['userlogin'], request_body=request_body)
    @action(methods=['post'], detail=False)
    def user_logout(self, request):
        str_token = request.META.get("HTTP_TOKEN", "")
        UserToken.objects.filter(token=str_token).delete()
        return success_response_with_data(msg='登出成功')
        pass


    #
    # @action(methods=['post'], detail=False)
    # def user_list(self, request):
    #     if request.method == 'POST':
    #         data = json.loads(request.body.decode('utf8'))
    #         current_page = data.get("pagenum", 1)
    #         page_size = data.get("pagesize", 10)
    #         query = data.get("query", '')
    #
    #     if request.method == 'GET':
    #         current_page = request.GET.get("pagenum", 1)
    #         page_size = request.GET.get("pagesize", 10)
    #         query = request.GET.get("query", '')
    #
    #     if current_page < 1:
    #         current_page = 1
    #     # 为避免大数据量，用这种方式比较合适，不要用Paginator
    #     start_row = (current_page - 1) * page_size
    #     end_row = current_page * page_size
    #
    #     try:
    #         objects = User.objects
    #         if len(query):
    #             objects = objects.filter(username__contains=query)
    #         objects = objects.all()
    #         total = objects.count()
    #         rows = objects[start_row:end_row]
    #         logger.debug(f"rows.query {rows.query}")
    #
    #     except ObjectDoesNotExist:
    #         logger.debug("没有发现记录")
    #         return list_response()
    #
    #     serializer = UserSerializer(rows, many=True)
    #
    #     return list_response(serializer.data, total, page_size, current_page, self.table_name)

